	//www.wcs-lagerhaus.de
/*
 Race: Traxex - The Drow Ranger
 Author(s): Vulpone&Revan
 Version: 1.0
 */


#include <sourcemod>
#include <sdktools>
#include "W3SIncs/War3Source_Interface"

new SKILL_ARROWS, SKILL_MARKMAN, SKILL_TRUESHOT, ULT_SILENCE;
new thisRaceID;
new Handle:ultCooldownCvar;
new BeamSprite,HaloSprite;
new bool:bUlt[MAXPLAYERS];

new Float:Restriction[MAXPLAYERS];


//sounds 
new String:frostsnd[]="war3source/traxex/icehit.wav";
new String:damagesnd[]="war3source/traxex/bowhit.wav";
new String:ultOn[]="war3source/traxex/touch.wav";

//Skill #1: arrows
new Float:FrostChance[5]={0.0,0.05,0.15, 0.20, 0.30};
new Float:AttackFrost[5]={1.0, 0.95, 0.90, 0.85, 0.80};
new Float:MoveFrost[5]={1.0, 0.90, 0.80, 0.70, 0.60};

//Skill #2: Markmanship
new Float:speed[5]={1.0, 1.15, 1.22, 1.27, 1.34};
new Float:grav[5]={1.0, 0.9, 0.8, 0.75, 0.70};

//Skill #3: Trueshot Aura
new Float:ExtraAura[5]={0.0, 0.07, 0.14, 0.21, 0.28};
new Float:AuraChance=0.30;
new Float:AuraRange[5]={0.0, 100.0, 250.0, 300.0, 350.0};

//Skill #4:Silence
new Float:SilenceRadius[5]={0.0, 100.0, 200.0, 300.0, 500.0};
new Float:SilenceDuration[5]={0.0, 3.0, 5.0, 6.0, 7.0};





//coding starts HERE

public Plugin:myinfo = 
{
	name = "War3Source Race - Traxex",
	author = "Vulpone",
	description = "The Traxex race for War3Source",
	version = "1.0",
	url = "www.wcs-lagerhaus.de"
};

public OnPluginStart()
{
	ultCooldownCvar=CreateConVar("war3_trax_ult_cooldown","30.0","Ultimate colldown for silence");
}	

public OnWar3LoadRaceOrItemOrdered(num)
{
	if( num == 200)
	{
		thisRaceID=War3_CreateNewRace("Traxex - The Drow Ranger","traxexranger");
		SKILL_ARROWS=War3_AddRaceSkill(thisRaceID,"Frost Arrows","Induces a freezing effect to the hero's attacks. Each attack slows the enemy's movement and attack rates. (30% chance)",false,4);
		SKILL_MARKMAN=War3_AddRaceSkill(thisRaceID,"Markmanship","The Ranger's accuracy has increased, giving her more agility.\nGain up to 34% speed and 30% lower gravity!",false,4);
		SKILL_TRUESHOT=War3_AddRaceSkill(thisRaceID,"Trueshot Aura", "An aura that gives friendly nearby units bonus damage to their ranged attacks with a 30% chance.", false, 4);
		ULT_SILENCE=War3_AddRaceSkill(thisRaceID,"Silence","Confuse enemies in a target area of 100-500 AoE, preveting them from casting spells.",true,4); 
		War3_CreateRaceEnd(thisRaceID);
	}
}


public OnMapStart() 
{
	PrecacheModel("effects/strider_pinch_dudv.vmt");
	War3_PrecacheSound(frostsnd);
	War3_PrecacheSound(damagesnd);
	War3_PrecacheSound(ultOn);
	BeamSprite=PrecacheModel("sprites/plasmabeam.vmt", true);
	HaloSprite=PrecacheModel("materials/sprites/halo01.vmt");
}

public OnWar3EventSpawn(client)
{
	if(War3_GetRace(client) == thisRaceID)
	{
		InitPassiveSkills(client);
		GivePlayerItem(client, "weapon_glock");
		GivePlayerItem(client, "weapon_xm1014");
		War3_WeaponRestrictTo(client,thisRaceID,"weapon_xm1014;weapon_glock;weapon_knife;weapon_c4");
	}
	if(War3_GetRace(client) != thisRaceID)
	{
		War3_SetBuff(client, fMaxSpeed, thisRaceID, 1.0);
		War3_SetBuff(client, fLowGravitySkill, thisRaceID, 1.0);
		War3_WeaponRestrictTo(client,thisRaceID,"");
	}
	
}

public OnRaceChanged( client, oldrace, newrace )
{
	if( newrace != thisRaceID )
	{
		War3_SetBuff( client, fMaxSpeed, thisRaceID, 1.0 );
		War3_SetBuff( client, fLowGravitySkill, thisRaceID, 1.0 );
		War3_WeaponRestrictTo(client,thisRaceID,"");
	}
	if(newrace == thisRaceID && ValidPlayer(client, true))
	{
		GivePlayerItem(client, "weapon_glock");
		GivePlayerItem(client, "weapon_xm1014");
	}
}

public InitPassiveSkills(client)
{
	if(ValidPlayer(client, true))
	{
		new skilllvl = War3_GetSkillLevel(client, thisRaceID, SKILL_MARKMAN);
		if( skilllvl > 0)
		{
			War3_SetBuff(client, fMaxSpeed, thisRaceID, speed[skilllvl]);
			War3_SetBuff(client, fLowGravitySkill, thisRaceID, grav[skilllvl]);
		}
	}
}

public OnW3TakeDmgBulletPre(victim,attacker,Float:damage)
{
	new skilllvl = War3_GetSkillLevel(attacker, thisRaceID, SKILL_ARROWS);
	new skillaura = War3_GetSkillLevel(attacker, thisRaceID, SKILL_TRUESHOT);
	new race_attacker=War3_GetRace(attacker);
	if(ValidPlayer(attacker, true) && ValidPlayer(victim, true))
	{
		new vteam = GetClientTeam( victim );
		new ateam = GetClientTeam( attacker );
		if(vteam != ateam) {
			//arrows frost
			if(skilllvl > 0 && race_attacker == thisRaceID)
			{
				if(GetRandomFloat(0.01, 1.0) <= FrostChance[skilllvl])
				{
					if(!W3HasImmunity(victim, Immunity_Skills))
					{
					
						War3_SetBuff(victim,fSlow,thisRaceID,MoveFrost[skilllvl]);
						War3_SetBuff(victim,fAttackSpeed,thisRaceID,AttackFrost[skilllvl]);
						W3FlashScreen(victim,RGBA_COLOR_BLUE);
						PrintHintText(attacker, "Frost Arrows!");
						EmitSoundToAll(frostsnd, attacker);
						EmitSoundToAll(frostsnd, victim);
						CreateTimer(1.2, Timer_RemoveAll, victim);
						new Float:myVec[3];
						GetClientAbsOrigin(attacker, myVec);
						new Float:endVec[3];
						GetClientAbsOrigin(victim, endVec);
						
						endVec[2] += 30;
						myVec[2] += 30;
						
						TE_SetupBeamPoints(myVec, endVec, BeamSprite, HaloSprite, 0, 15, 1.4, 5.0, 10.0, 1, 2.0, {175,201,255,222}, 20);
						TE_SendToAll();
						
					}
				}
			}
			//trueshot aura
			if(skillaura > 0 && GetRandomFloat(0.01, 1.0) <= AuraChance )
			{
				for(new client = 1; client <= MaxClients; client++)
				{
					if(ValidPlayer(client,true)) {
						if(War3_GetRace(client) == thisRaceID && GetClientTeam(client) == ateam)
						{
							new Float:AttackerPos[3];
							GetClientAbsOrigin(attacker, AttackerPos);
							new Float:iVec[3];
							GetClientAbsOrigin(client, iVec);
							new Float:radius = AuraRange[skillaura];
							if(GetVectorDistance(iVec, AttackerPos) <= radius)
							{
								if(!W3HasImmunity(victim, Immunity_Skills))
								{
									War3_DamageModPercent(ExtraAura[skillaura]+1.0);
									EmitSoundToAll(damagesnd, victim);
									EmitSoundToAll(damagesnd, attacker);
									W3FlashScreen(victim,RGBA_COLOR_RED);
								}
							}
							else
							{
								War3_DamageModPercent(1.0);
							}
						}
					}
				}
			}
		}
	}
}

public Action:Timer_RemoveAll(Handle:timer, any:victim)
{
	if(ValidPlayer(victim, false))
	{
		War3_SetBuff(victim,fSlow,thisRaceID,1.0);
		War3_SetBuff(victim,fAttackSpeed,thisRaceID,1.0);
	}
}

public OnUltimateCommand(client,race,bool:pressed)
{
	new skillult = War3_GetSkillLevel(client, thisRaceID, ULT_SILENCE);
	if(ValidPlayer(client, true) && skillult > 0 && race == thisRaceID && pressed)
	{
		if(War3_SkillNotInCooldown(client,thisRaceID,ULT_SILENCE,true ))
		{
			new Float:client_location[3];
			GetClientAbsOrigin(client,client_location);
			client_location[2]+=30;
			new Float:radius = SilenceRadius[skillult];
			bUlt[client] = true;
			CreateTimer(SilenceDuration[skillult], Timer_UltGone, client);
			CreateTimer(0.1,Effects,client);
			
			
			
			
			while(bUlt[client] == true && Restriction[client] < GetGameTime() - 2.0)
			{
				TE_SetupBeamRingPoint(client_location, 10.0, SilenceRadius[skillult], BeamSprite, HaloSprite, 0, 20, 1.0, 10.0, 1.0, {173,90,255,225}, 40, 0);
				TE_SendToAll(1.0);
				
				TE_SetupBeamRingPoint(client_location, 10.0, SilenceRadius[skillult], BeamSprite, HaloSprite, 0, 20, 1.0, 10.0, 1.0, {173,90,255,225}, 40, 0);
				TE_SendToAll(1.5);
			
				TE_SetupBeamRingPoint(client_location, 10.0, SilenceRadius[skillult], BeamSprite, HaloSprite, 0, 20, 1.0, 10.0, 1.0, {173,90,255,225}, 40, 0);
				TE_SendToAll(SilenceDuration[skillult]-2.0);
			
			
				TE_SetupBeamRingPoint(client_location, 10.0, SilenceRadius[skillult], BeamSprite, HaloSprite, 0, 20, 1.0, 10.0, 1.0, {173,90,255,225}, 40, 0);
				TE_SendToAll(SilenceDuration[skillult]-1.0);
				
				Restriction[client]=GetGameTime();
				
			}
			
			
			new Enviorment = CreateEntityByName("env_smokestack");    
			if(Enviorment)
			{
				DispatchKeyValue( Enviorment, "SmokeMaterial", "effects/strider_pinch_dudv.vmt" );
				DispatchKeyValue( Enviorment, "RenderColor", "128 0 255" );
				DispatchKeyValue( Enviorment, "SpreadSpeed", "300" );
				DispatchKeyValue( Enviorment, "RenderAmt", "100" );
				DispatchKeyValue( Enviorment, "JetLength", "400" );
				DispatchKeyValue( Enviorment, "RenderMode", "0" );
				DispatchKeyValue( Enviorment, "Initial", "0" );
				DispatchKeyValue( Enviorment, "Speed", "144" );
				DispatchKeyValue( Enviorment, "Rate", "150" );
				DispatchKeyValueFloat( Enviorment, "BaseSpread", 33.0 );
				DispatchKeyValueFloat( Enviorment, "StartSize", 100.0 );
				DispatchKeyValueFloat( Enviorment, "EndSize", 200.0 );
				DispatchKeyValueFloat( Enviorment, "Twist", 22.0 );
				DispatchSpawn(Enviorment);
				TeleportEntity(Enviorment, client_location, NULL_VECTOR, NULL_VECTOR);
				AcceptEntityInput(Enviorment, "TurnOn");
				CreateTimer( 3.0, Timer_TurnOffEntity, Enviorment );
				CreateTimer( 3.5, Timer_RemoveEntity, Enviorment );
			}
			
			
			War3_CooldownMGR(client,GetConVarFloat(ultCooldownCvar),thisRaceID,ULT_SILENCE,_,_);
			
			for(new i = 1; i <= MaxClients; i++)
			{
				if(GetClientTeam(i) != GetClientTeam(client) && ValidPlayer(i, false))
				{
					new Float:iVec[3];
					GetClientAbsOrigin(client, iVec);
					
					new Float:enemyVec[3];
					GetClientAbsOrigin(i, enemyVec);
					
					
					enemyVec[2] += 35;
					iVec[2] += 30;
						
					TE_SetupBeamPoints(iVec, enemyVec, BeamSprite, HaloSprite, 0, 15, 1.4, 5.0, 10.0, 1, 2.0, {173,90,255,255}, 20);
					TE_SendToAll(0.0);
					

					enemyVec[2] -= 35;
					iVec[2] -= 30;
					

					if(GetVectorDistance(iVec, enemyVec) <= radius)
					{
						War3_SetBuff(i,bSilenced,thisRaceID,true);
						PrintHintText(i, "Affected by Silence!");
						CreateTimer(SilenceDuration[skillult], Timer_SilenceGone, i);
					}
				}
			}
		}
	}		
}


public Action:Timer_UltGone(Handle:timer, any:client)
{
	bUlt[client] = false;
}

public Action:Timer_SilenceGone(Handle:timer, any:i)
{
	War3_SetBuff(i, bSilenced, thisRaceID, false);
}
	

public Action:Effects(Handle:t,any:client)
{
	if(bUlt[client] != false)
	{
		EmitSoundToAll(ultOn,client);
		CreateTimer(1.6,Effects,client);
	}

}

public Action:Timer_TurnOffEntity( Handle:timer, any:edict )
{
	if (edict > 0 && IsValidEdict(edict))
	AcceptEntityInput( edict, "TurnOff" );
}

public Action:Timer_RemoveEntity( Handle:timer, any:edict )
{
	if (edict > 0 && IsValidEdict(edict))
	AcceptEntityInput( edict, "Kill" );
}